import os
import json
import requests
import urllib3
from requests.exceptions import RequestException
from appserv.serv.config import dblock
from dataclasses import asdict
from decimal import Decimal

# 禁用SSL警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# 豆包API配置
base_url = "https://ark.cn-beijing.volces.com/api/v3/chat/completions"
api_key = "ffe0f46f-b3ca-4bf6-b94d-1958b0d0f196"
model = "doubao-1-5-pro-32k-250115"


def query_grade(stu_no: str) -> str:
    with dblock() as cur:
        cur.execute(
            """
            SELECT s.name as stu_name, c.name as course_name, g.grade 
            FROM course_grade as g
            INNER JOIN student as s ON g.stu_sn = s.sn
            INNER JOIN course as c  ON g.cou_sn = c.sn            
            WHERE s.no = %(stu_no)s 
            """,
            {"stu_no": stu_no},
        )

        items = [asdict(row) for row in cur]

        res = json.dumps(items, ensure_ascii=False, default=default_serializer)
        return res


# 正确的 tools 定义方式
tools = [
    {
        "type": "function",
        "function": {
            "name": "query_grade",
            "parameters": {
                "type": "object",
                "properties": {
                    "stu_no": {
                        "type": "string",
                        "description": "学号"
                    }
                },
                "required": ["stu_no"]
            },
            "description": "根据学号查询学生的成绩"
        }
    }
]

system_prompt = r"""
你是一个用户的专属智能助手，负责处理用户请求。你的任务是：
1. 分析用户输入，确定请求与成绩相关。
2. 系统的使用对象是"教秘"，不是学生本人，假设本系统没有教师方面信息
3. 用户可以查询其它用户的成绩。
"""


def process_query(query: str) -> str:
    messages = [
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": query},
    ]

    print(f"\n[1]REQ: {messages}\n")

    try:
        # 第一次调用豆包API
        response = requests.post(
            base_url,
            headers={
                "Content-Type": "application/json",
                "Authorization": f"Bearer {api_key}"
            },
            json={
                "model": model,
                "messages": messages,
                "tools": tools,
                "temperature": 0.7,
            },
            proxies={'http': None, 'https': None},  # 禁用代理
            verify=False,  # 禁用SSL验证
            timeout=30  # 设置超时时间
        )

        if response.status_code != 200:
            raise Exception(f"API调用失败: {response.status_code}, {response.text}")

        response_data = response.json()
        print(f"[1]RES: {response_data}\n")

        if "choices" not in response_data or len(response_data["choices"]) == 0:
            raise Exception("API返回格式异常，缺少choices字段")

        choice = response_data["choices"][0]

        # 判断是否需要调用工具函数
        if choice.get("finish_reason") == "tool_calls" and "tool_calls" in choice["message"]:
            messages.append(choice["message"])

            for tool_call in choice["message"]["tool_calls"]:
                func_name = tool_call["function"]["name"]
                func_args = json.loads(tool_call["function"]["arguments"])

                if func_name == "query_grade":
                    result = query_grade(**func_args)
                    messages.append(
                        {
                            "role": "tool",
                            "tool_call_id": tool_call["id"],
                            "name": func_name,
                            "content": result
                        }
                    )

            print(f"[2]REQ: {messages}\n")

            # 第二次调用豆包API
            second_response = requests.post(
                base_url,
                headers={
                    "Content-Type": "application/json",
                    "Authorization": f"Bearer {api_key}"
                },
                json={
                    "model": model,
                    "messages": messages,
                    "temperature": 0.7,
                },
                proxies={'http': None, 'https': None},  # 禁用代理
                verify=False,  # 禁用SSL验证
                timeout=30  # 设置超时时间
            )

            if second_response.status_code != 200:
                raise Exception(f"第二次API调用失败: {second_response.status_code}, {second_response.text}")

            second_data = second_response.json()
            print(f"[2]RES: {second_data}\n")

            if "choices" not in second_data or len(second_data["choices"]) == 0:
                raise Exception("第二次API返回格式异常")

            return second_data["choices"][0]["message"]["content"]

        else:
            return choice["message"]["content"]
            
    except requests.exceptions.RequestException as e:
        print(f"网络请求错误: {str(e)}")
        return "抱歉，网络连接出现问题，请稍后重试。"
    except Exception as e:
        print(f"处理查询时发生错误: {str(e)}")
        return "抱歉，处理您的请求时出现错误，请稍后重试。"


def default_serializer(obj):
    if isinstance(obj, Decimal):
        return float(obj)
    raise TypeError(f"Object of type {type(obj)} is not JSON serializable")


if __name__ == "__main__":
    query = "我的课程是否都通过了？"
    print("问:", query)
    answer = process_query(query)
    print("答:", answer)